/**
 * @file
 *           base64.h
 * @brief
 *          <fillin>purpose
 *
 * @par Author (last changes):
 *          - Herea Adrian
 *          
 * @par Description:
 *
 *
 * @par Module-History:
 * @verbatim
 *  Date        Author				Reason
 *  15.01.2010  Herea Adrian         Initial creation
 *
 * @endverbatim
 *
 * @par Copyright Notice:
 * @verbatim
 * Copyright (C) 2010
 * All Rights Reserved.
 * The reproduction, transmission or use of this document or its contents is
 * not permitted without express written authority.
 * Offenders will be liable for damages. All rights, including rights created
 * by patent grant or registration of a utility model or design, are reserved.
 **/

#include "stdafx.h"

#include <string>
#include <stdio.h>
#include "Protocol.h"

using namespace std;

Protocol::Protocol(void)
{
}

const string
Protocol::protocol(Command cmd)
{
  string protocol;
  protocol = string("<xstl>");
  protocol += string("<cmd id=\"");
  char ID[12];
  int sizeId = 0;
  //itoa(cmd.getId(),buffer,10);
  sizeId = sprintf_s(ID, 12, "%d", cmd.getId());
  protocol += string(ID, sizeId);
  protocol += string("\">");
  list<Param> params = cmd.getParams();
  list<Param>::iterator it;
  for (it = params.begin(); it != params.end(); it++)
    {
      protocol += "<par name=\"" + it->getName() + "\">" + it->getValue()
          + "</par>";
    }
  protocol += string("</cmd>");
  protocol += string("</xstl>");

  return protocol;
}

Command*
Protocol::command(string protocol)
{
  Command* cmd = NULL;
  string command = popChild(protocol);
  string id = nodeAtribute(command);
  int ID;
  sscanf(id.c_str(), "%d", &ID);
  cmd = new Command();
  cmd->setId(ID);
  string parametre = popChild(command);
  string sValue;
  string sName;
  int countParameters = 1;

  while (parametre != "")
    {
      //	printf ("%s \n",command.c_str() );
      //	printf ("%s \n",parametre.c_str() );
      sName = nodeAtribute(parametre);
      sValue = nodeValue(parametre);
      Param* pParam = new Param(sName, sValue);
      cmd->addParam(*pParam);
      parametre = popChild(command);
      sValue = "";
      sName = "";
      countParameters++;
    }
  //	printf ("%d parameters\n", countParameters);

  return cmd;
}

string
Protocol::attribute(string& protocol, string attr)
{
  string sVal;
  attr = attr + "=\"";
  size_t posBegin = protocol.find(attr);
  if (posBegin != string::npos)
    {
      protocol = protocol.substr(posBegin + attr.length());
      size_t posEnd = protocol.find('"');
      if (posEnd != string::npos)
        {
          sVal = protocol.substr(0, posEnd);
          protocol = protocol.substr(posEnd + 1);
        }
    }
  return sVal;
}

bool
Protocol::nodeValue(string& protocol, string sName, string sValue)
{
  string sBegin = "<" + sName + " " + sValue + ">";

  string sEnd = "</" + sName + ">";

  size_t posBegin = protocol.find(sBegin);
  if (posBegin == string::npos)
    {
      return false;
    }

  protocol = protocol.substr(posBegin + sBegin.length());

  size_t posEnd = protocol.find(sEnd);
  if (posEnd == string::npos)
    {
      return false;
    }

  sValue = protocol.substr(0, posEnd);
  protocol = protocol.substr(posEnd + sEnd.length());

  return true;
}

//short description
//funtion return the first child of curent xml tree and remove it from tree\
//the rest of the tree is not afected
string
Protocol::popChild(string & protocol)
{
  size_t posBeginEnd = protocol.find('>');
  string sBegin = protocol.substr(0, posBeginEnd + 1);
  protocol = protocol.substr(posBeginEnd + 1);
  size_t posChildBeginStart = protocol.find('<');
  string sChild = "";

  if (posChildBeginStart != string::npos)
    {
      size_t posChildBeginEnd = protocol.find(">");
      if (posChildBeginEnd != string::npos)
        {
          string sChildTag = protocol.substr(0, posChildBeginEnd + 1);
          string sChildEndTag = "</" + sChildTag.substr(1, sChildTag.find(" ")
              - 1) + ">";
          size_t posChildEnd = protocol.find(sChildEndTag);
          if (posChildEnd != string::npos)
            {
              sChild
                  = protocol.substr(0, (posChildEnd + sChildEndTag.length()));
              protocol = protocol .substr(posChildEnd + sChildEndTag.length());
            }
        }
      protocol = sBegin + protocol;
    }
  return sChild;
}

//return the content  of curent node
//the node is note affected
string
Protocol::nodeValue(std::string &protocol)
{
  size_t posBeginEnd = protocol.find(">");
  string sBegin = protocol.substr(0, posBeginEnd + 1); //begin tag
  string sValue;
  string sEnd = "</" + sBegin.substr(1, sBegin.find(" ") - 1) + ">"; //end tag
  sValue = protocol.substr(posBeginEnd + 1);
  size_t posEnd = sValue.find(sEnd);

  if (posEnd != string::npos)
    {
      sValue = sValue.substr(0, posEnd);
    }
  else
    {
      sValue = "";
    }
  return sValue;
}

//return the first atribute 
//the xml tree is not affected
string
Protocol::nodeAtribute(std::string &protocol)
{
  string sVal = "";
  size_t posBegin = protocol.find("=\"");

  if (posBegin != string::npos)
    {
      sVal = protocol.substr(posBegin + 2); // =" ,two char
      size_t posEnd = sVal.find('"');
      if (posEnd != string::npos)
        {
          sVal = sVal.substr(0, posEnd);
        }
      else
        {
          sVal = "";
        }
    }
  return sVal;

}

Protocol::~Protocol(void)
{
}
